

/**
 * gps传感器获取gps信息类
 *
 * @author cjp
 */
public class GpsLigthSensationSensor extends AbstractExtendDevice implements IGpsLigthSensationDevcie {

	private static final int MAX_LATITUDE = 90;
	private static final int MAX_LONGITUDE = 180;
	public static final DecimalFormat LONGITUDE_AND_LATITUDE_FORMATE = new DecimalFormat("#0.0000");

	private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	/**
	 * 光照度
	 */
	private double lux;
	/**
	 * 经度
	 */
	private String longitude = "12014.2743";
	/**
	 * 东经/西经
	 */
	private char longitedeSymbol = 'E';
	/**
	 * 纬度
	 */
	private String latitude = "3031.9629";
	/**
	 * 南纬/北纬
	 */
	private char latitudeSymbol = 'N';
	/**
	 * GPS是否有信号
	 */
	private boolean GPSUseful = false;

	String satelliteQuantity = "00";
	String signalNoise = "00";

	private int extendNum = 0;

	public static final Pattern GPS_PATTERN = Pattern.compile("<LUX_GPS_DATA_(?<lux>[0-9.]{1,10})/(?<gps>.{13,})>");

	public static final Pattern GPS1_PATTERN = Pattern.compile("<LUX_GPS_DATA_(?<lux>[0-9.]{1,10})/GPS_DATA_ERROR>");

	public GpsLigthSensationSensor(int extendNum, ExtendDeviceEnum deviceType) {

		super(extendNum, ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(extendNum).getDeviceType());
		this.extendNum = extendNum;
		if (ExtendDeviceEnum.GPS.equals(deviceType)) {
			gpsInformationTask();
		} else if (ExtendDeviceEnum.LIGHT.equals(deviceType)) {
			updateInformationTask();
		}
	}

	private void gpsInformationTask() {

		updateGpsInformation();
		gpsThreadPool.schedule(() -> {
			// 如果检查周期小于30S 则不继续更新等待下次
			if (System.currentTimeMillis() - getLastQueryTime() < 30 * 1000) {
			} else {
				updateGpsInformation();
			}
		}, 60, TimeUnit.SECONDS);
	}

	public GpsLigthSensationSensor updateGpsInformation() {

		ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.GPS);
		String gpsInformation = JnIMethod.sendMessage2ExtendDeviceByRs485(115200, getExtendNum(), "<AT_CHECK0_GPS_DATA>", 200);
		if (gpsInformation == null) {
			getUnderDeviceInteractionBean().interactionFail();
			return this;
		} else {
			getUnderDeviceInteractionBean().interactionSuccess();
		}
		Matcher matcher = GPS_PATTERN.matcher(gpsInformation);
		setLastQueryTime();
		if (matcher.matches()) {
			String gpsInfoString = matcher.group("gps");
			parseGpsInfo(gpsInfoString);
			// matcher.group("time");

		} else {
			this.GPSUseful = false;
		}
		return this;
	}

	private void parseGpsInfo(String gpsInfoString) {

		String[] fieldStrings = gpsInfoString.split(",");
		if ("$GNGGA".equals(fieldStrings[0])) {
		this.latitude = fieldStrings[2];
		this.latitudeSymbol = fieldStrings[3].charAt(0);

		this.longitude = fieldStrings[4];
		this.longitedeSymbol = fieldStrings[5].charAt(0);

		this.satelliteQuantity = fieldStrings[7];
		signalNoise = fieldStrings[14];
		
		} else {
			DateFormat format = new SimpleDateFormat("ddMMyyHHmmss");
			String dateString = fieldStrings[9].concat(fieldStrings[1]);
			
			try {
				Date datetime = format.parse(dateString);
				CmdUtil.setDate(datetime);	
			} catch (Exception ex) {
				log.error("set datetime by gps error", ex);
			}

			
		}
		this.GPSUseful = true;
	}

	private void updateInformationTask() {

		updateGpsLigthInformation();
		gpsLightThreadPool.schedule(() -> {
			// 如果检查周期小于30S 则不继续更新等待下次
			if (System.currentTimeMillis() - getLastQueryTime() < 30 * 1000) {
			} else {
				updateInformationTask();
			}
		}, 60, TimeUnit.SECONDS);
	}

	/**
	 * 更新设备信息 获取最新的数据
	 */
	public GpsLigthSensationSensor updateGpsLigthInformation() {

		// 如果查询时间小于10秒 则不更新数据
		String gpsInformation = JnIMethod.sendMessage2ExtendDeviceByRs485(115200, getExtendNum(), "<AT_CHECK0_LUX_GPS_DATA>", 200);
		if (gpsInformation == null) {
			getUnderDeviceInteractionBean().interactionFail();
			return this;
		} else {
			getUnderDeviceInteractionBean().interactionSuccess();
		}
		Matcher matcher1 = GPS1_PATTERN.matcher(gpsInformation);
		if (matcher1.matches()) {
			this.GPSUseful = false;
			this.lux = Double.parseDouble(matcher1.group("lux"));
			if (this.lux < 99999 && this.lux >= 0) {
				ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.LIGHT);
				IExtendDevice ie = ExtendDeviceManager.getInstance().getExtendDevice(ExtendDeviceEnum.LIGHT);
			}
			return this;
		}
		Matcher matcher = GPS_PATTERN.matcher(gpsInformation);
		setLastQueryTime();
		if (matcher.matches()) {
			this.lux = Double.parseDouble(matcher.group("lux"));
			String gpsInfoString = matcher.group("gps");
			parseGpsInfo(gpsInfoString);
		} else {
			this.lux = -1;
			this.GPSUseful = false;
		}
		if (this.GPSUseful == true && (this.lux > 99999 || this.lux < 0)) {
			ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.GPS);

			IExtendDevice ie = ExtendDeviceManager.getInstance().getExtendDevice(ExtendDeviceEnum.GPS);

		} else if (this.GPSUseful == false && this.lux < 99999) {
			ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.LIGHT);
			IExtendDevice ie = ExtendDeviceManager.getInstance().getExtendDevice(ExtendDeviceEnum.LIGHT);
		} else if (this.GPSUseful == true && this.lux < 99999 && this.lux >= 0) {
			ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.GPS_LIGHT);
			IExtendDevice ie = ExtendDeviceManager.getInstance().getExtendDevice(ExtendDeviceEnum.GPS_LIGHT);
		} else {
			ExtendDeviceManager.getInstance().getExtendDeviceByExtendNum(this.extendNum).setDeviceType(ExtendDeviceEnum.GPS);
		}
		Map<String, Object> dataMap = new HashMap<>();
		dataMap.put(EventRegisterCenter.DEVICE_NAME, ExtendDeviceEnum.GPS.getDeviceName());
		EventRegisterCenter.getInstance().triggerRegisterTask(EventRegisterCenter.DATA_EXCHANGE, dataMap);
		return this;
	}

	public static final DecimalFormat LAT_AND_LNG_FORMAT = new DecimalFormat("#0.000000");

	/**
	 * @return 获取格式化后的位置 如12.266E_125.36N
	 */
	@Override
	public String returnForFCommand() {

		if (!isGPSUseful()) {
			return "";
		}
		StringBuilder stringBuilder = new StringBuilder();
		stringBuilder.append(latitude).append(latitudeSymbol == 0 ? "N" : latitudeSymbol).append('_');
		stringBuilder.append(longitude).append(longitedeSymbol == 0 ? "E" : longitedeSymbol);
		stringBuilder.append('_').append(satelliteQuantity);
		stringBuilder.append('_').append(signalNoise);
		return stringBuilder.toString();
	}

	/**
	 * 资源互斥通过拓展通道自带的锁实现
	 * 尝试通过485获取GPS信号
	 * 
	 * @return
	 */
	private static double[] getGpsInfomation() {

		return new double[1];
	}

	@Override
	public boolean isGPSUseful() {

		return GPSUseful;
	}

	@Override
	public double getLux() {

		return lux;
	}

	public static final DecimalFormat LUX_FORMAT = new DecimalFormat("00000");

	/**
	 * 返回给P指令使用
	 * 
	 * @return
	 */
	@Override
	public String returnForPCommand() {

		return LUX_FORMAT.format(lux);
	}

	@Override
	public ILightSensationDevice updateLightSensationInformation() {

		return updateGpsLigthInformation();
	}
}
